import os
import uuid

from langchain.agents import StructuredChatAgent, AgentExecutor
from langchain.memory import ConversationBufferMemory
from langchain_core.prompts import PromptTemplate
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(
    model_name="qwen-plus",
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    temperature=0,
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
)


@tool(
    description="查询指定城市的指定日期的天气数据,参数:city,中文城市名,字符串,示例:北京,上海;date,日期,字符串,示例:2025年10月11日,返回值:天气数据"
)
def WeatherTool(city: str, date: str) -> str:
    # 基本参数配置
    apiUrl = 'http://apis.juhe.cn/simpleWeather/query'  # 接口请求URL
    apiKey = '89d99d8a8f8f20938ebfb99911c63367'  # 在个人中心->我的数据,接口名称上方查看
    # 接口请求入参配置
    requestParams = {
        'key': apiKey,
        'city': city,
    }

    import requests
    # 发起接口网络请求
    response = requests.get(apiUrl, params=requestParams)
    # 解析响应结果
    if response.status_code == 200:
        responseResult = response.json()
        print(responseResult)
        temperature = responseResult.get("result").get("realtime").get("temperature")
        humidity = responseResult.get("result").get("realtime").get("humidity")
        direct = responseResult.get("result").get("realtime").get("direct")
        power = responseResult.get("result").get("realtime").get("power")

        return f"城市:{city},日期:{date},天气：温度:{temperature}℃,湿度:{humidity}%rh,风向:{direct},风力{power}"

    else:
        return "查询失败"


@tool(
    description="预订指定城市的指定日期的酒店房间,参数:city,中文城市名,字符串,示例:北京,上海;date,日期,字符串,示例:2025年10月11日;guests,入住人数,数字,示例:2;room_type,房间类型,字符串,示例:标准间,返回值:酒店数据订单号"
)
def HoteTool(city: str, date: str, guests: int, room_type: str) -> str:
    if not all([city, date, guests, room_type]):
        return "参数错误,请提供:具体的城市名称, 入住时间, 入住人数, 房间类型"

    order_id = str(uuid.uuid4())
    return f"订单号:{order_id},城市:{city},日期:{date},入住人数:{guests},房间类型:{room_type},开房已成功"


tools = [WeatherTool, HoteTool]

memory = ConversationBufferMemory(
    memory_key="chat_history",
    return_messages=True
)

prompt_template = """
你是一个天气查询和酒店预订的智能机器人,请根据用户的请求,完成功能

使用以下工具:
{tools}

使用规则:
1:先理解问题:无需工具则直接回答,需要工具则调用工具(根据工具的描述匹配)
2:调用工具必须用格式：```json{{"name":"工具名","parameters":{{"参数名":"参数值"}}}}```（参数需齐全）；
3:拿到工具结果后, 判断是否继续调用工具, 如果需要继续调用工具,则调用工具,否则整理,返回结果;
4:如果需要查询指定城市的指定日期的天气数据,调用WeatherTool工具
5:如果需要预订指定城市的指定日期的酒店房间,调用HoteTool工具




用户: {input}

"""

prompt = PromptTemplate(
    template=prompt_template,
    input_variables=["tools", "input", "chat_history"],
    partial_variables={
        "tools": "\n".join([f"{t.name}:{t.description}" for t in tools])
    }
)

agent = StructuredChatAgent.from_llm_and_tools(
    llm=llm,
    tools=tools,
    prompt=prompt,
    verbose=True,
    memory=memory
)

executor = AgentExecutor(
    agent=agent,
    tools=tools,
    verbose=True,
    handle_parsing_errors="参数格式错误!!!!!!!!",
    max_iterations=5,
    memory=memory
)

if __name__ == '__main__':
    while True:
        query = input("请输入问题:")
        res = executor.invoke({
            "input": query
        })
        print(res)
        print("当前记忆:", memory.buffer)
